<template>
    <div class="form-edit-container">


        <div class="left-board">
            <el-scrollbar class="left-scrollbar">
                <div class="components-list">
                    <div v-for="(item, listIndex) in leftComponents" :key="listIndex">
                        <div class="components-title">
                            <svg-icon name="component" />
                            {{ item.title }}
                        </div>
                        <draggable
                            :clone="cloneComponent"
                            :group="{ name: 'componentsGroup', pull: 'clone', put: false }"
                            :list="item.list"
                            :sort="false"
                            class="components-draggable"
                            draggable=".components-item"
                            @end="onEnd"
                        >
                            <div
                                v-for="(element, index) in item.list"
                                :key="index"
                                class="components-item"
                                @click="addComponent(element)"
                            >
                                <div class="components-body">
                                    <svg-icon :name="element.__config__.tagIcon" />
                                    {{ element.__config__.label }}
                                </div>
                            </div>
                        </draggable>
                    </div>
                </div>
            </el-scrollbar>
        </div>
        <div class="center-board">
            <el-scrollbar class="center-scrollbar">
                <el-row v-if="formConf" :gutter="formConf.gutter" class="center-board-row">
                    <el-row align="middle" justify="center" type="flex">
                        <el-col class="form-head-title">
                            <h4 class="form-name-text" contenteditable="true"
                                @blur="(event)=>{
                                    this.formConf.title=event.target.innerText;
                                    this.saveProjectInfo()}"
                            >
                                {{ formConf.title }}
                            </h4>
                        </el-col>
                    </el-row>
                    <el-row align="middle" justify="center" type="flex">
                        <el-col class="form-head-desc">
                            <Tinymce v-if="editDescription" :value="formConf.description" v-model="formConf.description"
                                     placeholder="请输入表单描述"
                                     @blur="editDescription=false" :catchData="saveProjectInfo" @input="saveProjectInfo"
                            />
                            <div v-else class="form-name-text"
                                 @click="editDescription=true" v-html="formConf.description"
                            />
                        </el-col>
                    </el-row>
                    <el-divider class="form-head-divider" />
                    <el-form
                        :disabled="formConf.disabled"
                        :label-position="formConf.labelPosition"
                        :label-width="formConf.labelWidth + 'px'"
                        :size="formConf.size"
                    >
                        <draggable :animation="340" :list="drawingList" class="drawing-board" group="componentsGroup"
                                   @end="onItemEnd"
                        >
                            <draggable-item
                                v-for="(item, index) in drawingList"
                                :key="item.renderKey"
                                :active-id="activeId"
                                :current-item="item"
                                :drawing-list="drawingList"
                                :form-conf="formConf"
                                :index="index"
                                @activeItem="activeFormItem"
                                @changeLabel="changeLabel"
                                @copyItem="drawingItemCopy"
                                @deleteItem="drawingItemDelete"
                            />
                        </draggable>
                        <div v-show="!drawingList.length" class="empty-info">
                            <img style="width: 20%" src="@/assets/images/form/form-bg.png">
                            <p>从左侧拖入或点选组件进行表单设计</p>
                        </div>
                    </el-form>
                </el-row>
            </el-scrollbar>
        </div>
        <right-panel
            :active-data="activeData"
            :form-conf="formConf"
            :show-field="!!drawingList.length"
            @tag-change="tagChange"
            @data-change="updateProjectItemInfo"
        />
    </div>
</template>

<script>
import draggable from 'vuedraggable'
import {debounce} from 'throttle-debounce'
import RightPanel from '@/components/DuoJuHe/Form/editor/RightPanel'

import {
    assistComponents,
    formConf,
    personalInfoComponents,
    selectComponents,
    layoutComponents
} from '@/components/DuoJuHe/Form/generator/config'

import {dbDataConvertForItemJson, formItemConvertData, deepClone} from '@/utils/form/utils/convert'
import drawingDefalut from '@/components/DuoJuHe/Form/generator/drawingDefalut'
import DraggableItem from '@/components/DuoJuHe/Form/editor/DraggableItem'
import {saveDrawingList, saveIdGlobal} from '@/utils/form/utils/cache'
import Tinymce from '@/components/DuoJuHe/Form/tinymce/index'
import {queryFormProjectResByProjectId, updateFormProject} from '@/api/form/formProject'
import {queryFormProjectItemPageResList, queryFormProjectItemMaxFormItemIdByProjectId,saveUpdateFormProjectItem,deleteFormProjectItem, updateFormProjectItemSort} from '@/api/form/formProjectItem'

let oldActiveId
let tempActiveData
let idGlobal

export default {
    components: {
        draggable,
        RightPanel,
        DraggableItem,
        Tinymce
    },
    data() {
        return {
            idGlobal,
            formConf: null,
            editDescription: true,
            selectComponents,
            labelWidth: 100,
            drawingList: drawingDefalut,
            drawingData: {},
            activeId: drawingDefalut.length != 0 ? drawingDefalut[0].formId : 0,
            formData: {},
            dialogVisible: false,
            generateConf: null,
            showFileName: false,
            activeData: drawingDefalut ? drawingDefalut[0] : null,
            saveDrawingListDebounce: debounce(340, saveDrawingList),
            saveIdGlobalDebounce: debounce(340, saveIdGlobal),
            projectId: null,
            leftComponents: [
                {
                    title: '辅助型组件',
                    list: assistComponents
                },
                {
                    title: '进阶型组件',
                    list: selectComponents
                },
                {
                  title: '扩展型组件',
                  list: personalInfoComponents
                }
            ]
        }
    },
    computed: {},
    watch: {
        // eslint-disable-next-line func-names
        'activeData.__config__.label': function(val, oldVal) {
            if (
                this.activeData.placeholder === undefined
                || !this.activeData.__config__.tag
                || oldActiveId !== this.activeId
            ) {
                return
            }
            this.activeData.placeholder = this.activeData.placeholder.replace(oldVal, '') + val
        },
        activeId: {
            handler(val) {
                oldActiveId = val
            },
            immediate: true
        },
        drawingList: {
            handler(val) {
                this.saveDrawingListDebounce(val, this.projectId)
                //if (val.length === 0) this.idGlobal = 100
            },
            deep: true
        },
        idGlobal: {
            handler(val) {
                if (val) {
                    this.saveIdGlobalDebounce(val, this.projectId)
                }
            },
            immediate: true
        }
    },
    created() {
      // 复制对象 避免修改改变原始对象
      this.formConf = JSON.parse(JSON.stringify(formConf))
      // 项目key
      this.projectId = this.$route.query.key
      // 获取表单配置
      this.queryFormProjectResByProjectId()
    },
    mounted() {
        // 复制对象 避免修改改变原始对象
       // this.formConf = JSON.parse(JSON.stringify(formConf))
        // 项目key
        this.projectId = this.$route.query.key
        // 获取表单配置
       // this.queryFormProjectResByProjectId()
        // 全局组件Id
        //this.queryFormProjectItemMaxFormItemIdByProjectId()
        // 从服务端获取
        this.queryProjectItems()
    },
    methods: {
      // 获取表单配置
      queryFormProjectResByProjectId() {
        queryFormProjectResByProjectId({"projectId":this.projectId}).then(res => {
            let data = res.data
            this.formConf.title = data.projectName
            this.formConf.projectId = data.projectId
            this.formConf.description = data.description
            this.idGlobal = data.maxFormItemId ? data.maxFormItemId : 100
          }
        )
      },

      // 全局组件Id
      queryFormProjectItemMaxFormItemIdByProjectId() {
        queryFormProjectItemMaxFormItemIdByProjectId({"projectId":this.projectId}).then(res => {
            let data = res.data
            this.idGlobal = data ? data : 100
          }
        )
      },

        //更新项目
        saveProjectInfo: debounce(430, true, function() {
          let form = {
            projectId: this.formConf.projectId?this.formConf.projectId:this.projectId,
            projectName: this.formConf.title,
            sort: 1,
            description: this.formConf.description
          };
          if (this.formConf.title==null||
            this.formConf.title===""||
            this.formConf.title===undefined){
            return
          }
          updateFormProject(form).then(() => {});
        }),
        updateProjectItemInfo(val) {
            let data = formItemConvertData(val, this.projectId)
            saveUpdateFormProjectItem(data).then(res => {})
        },
        deleteProjectItemInfo(val) {
            let data = formItemConvertData(val, this.projectId)
            deleteFormProjectItem(data).then(res => {})
        },

      async saveProjectItemInfo(item) {
            let isSuccess = false
            let params = formItemConvertData(item, this.projectId)
            let pItem = item
        await saveUpdateFormProjectItem(params).then(res => {
              let data = res.data
              pItem.sort = data.maxFormItemSort
              this.idGlobal = data.maxFormItemId ? data.maxFormItemId : 100
              isSuccess = true
            })
            // 如果是分页组件 刷新所有分页的页码
            if (item.typeId === 'FORM_PAGINATION') {
                this.updatePaginationList()
            }
           return isSuccess
        },
        updatePaginationList() {
            // 页总数
            const length = this.drawingList.filter(item => item.typeId === 'FORM_PAGINATION').length
            let curr = 1
            this.drawingList.forEach((item, index) => {
                if (item.typeId === 'FORM_PAGINATION') {
                    item.totalPageNum = length
                    item.currPageNum = curr++
                    this.$set(this.drawingList, index, item)
                }
            })
        },
      //根据项目id查询子项目
        queryProjectItems() {
          queryFormProjectItemPageResList({"projectId":this.projectId,"rows":0,"page":1}).then(res => {
              this.drawingList = res.data.records.map(item => dbDataConvertForItemJson(item))
              // 更新分页
              this.updatePaginationList()
            }
          )
        },
        activeFormItem(currentItem) {
            this.activeData = currentItem
            this.activeId = currentItem.__config__.formId
        },
        changeLabel(currentItem, value) {
            console.log(currentItem)
            console.log(value)
        },
        onEnd(obj) {
            if (obj.from !== obj.to) {
                this.activeData = tempActiveData
                this.activeId = this.idGlobal
                this.saveProjectItemInfo(tempActiveData).then(res =>{
                  if (res){
                    this.onItemEnd(obj)
                  }
              })
            }
        },
        onItemEnd(obj) {
            let params = {'projectId': this.projectId}
            if (this.drawingList[obj.newIndex - 1]) {
                let sort1 = this.drawingList[obj.newIndex - 1].sort
                params.beforePosition = sort1
            }
            if (this.drawingList[obj.newIndex + 1]) {
                let sort2 = this.drawingList[obj.newIndex + 1].sort
                params.afterPosition = sort2
            }
            params.formItemId = this.drawingList[obj.newIndex].__config__.formId
            params.type = this.drawingList[obj.newIndex].typeId
            if (params.beforePosition || params.afterPosition) {
              //重置排序
              updateFormProjectItemSort(params).then(res => {
                let data = res.data
                this.drawingList[obj.newIndex].sort = data.maxFormItemSort
                this.idGlobal = data.maxFormItemId ? data.maxFormItemId : 100
              })
            }
        },
        addComponent(item) {
            const clone = this.cloneComponent(item)
            this.saveProjectItemInfo(clone).then(res => {
              if (res){
                this.drawingList.push(clone)
                this.activeFormItem(clone)
              }
            })

        },
        cloneComponent(origin) {
            const clone = deepClone(origin)
            const config = clone.__config__
            config.span = this.formConf.span // 生成代码时，会根据span做精简判断
            this.createIdAndKey(clone)
            clone.placeholder !== undefined && (clone.placeholder += config.label)
            tempActiveData = clone
            return tempActiveData
        },
        createIdAndKey(item) {
            const config = item.__config__
            config.formId = ++this.idGlobal
            config.renderKey = `${config.formId}${+new Date()}` // 改变renderKey后可以实现强制更新组件
            if (config.layout === 'colFormItem') {
                item.__vModel__ = `field${this.idGlobal}`
            } else if (config.layout === 'rowFormItem') {
                item.__vModel__ = `field${this.idGlobal}`
                config.componentName = `row${this.idGlobal}`
                !Array.isArray(config.children) && (config.children = [])
                //delete config.label // rowFormItem无需配置label属性
            }
            if (Array.isArray(config.children)) {
                config.children = config.children.map(childItem => this.createIdAndKey(childItem))
            }
            return item
        },
        empty() {
            this.$confirm('确定要清空所有组件吗？', '提示', {type: 'warning'})
                .then(
                    () => {
                        this.drawingList = []
                        //this.idGlobal = 100
                    }
                )
        },
        drawingItemCopy(item, list) {
            let clone = deepClone(item)
            clone = this.createIdAndKey(clone)
            list.push(clone)
            this.saveProjectItemInfo(clone).then(res =>{
              if (res) {
                this.activeFormItem(clone)
              }
            })
            //this.saveProjectItemInfo(clone)
        },
        drawingItemDelete(index, list) {
            let item = list[index]
            list.splice(index, 1)
            this.$nextTick(() => {
                const len = this.drawingList.length
                if (len) {
                    this.activeFormItem(this.drawingList[len - 1])
                }
            })
            this.deleteProjectItemInfo(item)
        },
        tagChange(newTag) {
            newTag = this.cloneComponent(newTag)
            const config = newTag.__config__
            newTag.__vModel__ = this.activeData.__vModel__
            newTag.sort = this.activeData.sort
            config.formId = this.activeId
            config.span = this.activeData.__config__.span
            this.activeData.__config__.tag = config.tag
            this.activeData.__config__.tagIcon = config.tagIcon
            this.activeData.__config__.document = config.document
            this.activeData.typeId = newTag.typeId
            if (typeof this.activeData.__config__.defaultValue === typeof config.defaultValue) {
                config.defaultValue = this.activeData.__config__.defaultValue
            }
            Object.keys(newTag)
                .forEach(key => {
                    if (this.activeData[key] !== undefined) {
                        newTag[key] = this.activeData[key]
                    }
                })
            this.activeData = newTag
            this.updateProjectItemInfo(newTag)
            this.updateDrawingList(newTag, this.drawingList)
        },
        updateDrawingList(newTag, list) {
            const index = list.findIndex(item => item.__config__.formId === this.activeId)
            if (index > -1) {
                list.splice(index, 1, newTag)
            } else {
                list.forEach(item => {
                    if (Array.isArray(item.__config__.children)) this.updateDrawingList(newTag, item.__config__.children)
                })
            }
        }
    }
}
</script>

<style lang='scss'>
@import '@/assets/styles/form/home';
@import '@/assets/styles/form/index';
</style>
<style lang="scss" scoped>

.center-board {

  .center-board-row {
    margin-right: 10px;
  }

  .form-head-title {
    padding: 0 10px;
    text-align: center;

    .form-name-text:hover{
      border: 1px dashed #7b7b7b;
      min-height: 100px;
    }

  }

  .form-head-desc {
    padding: 0 10px;
  }

  .form-head-divider {
    margin-right: 10px;
    margin-left: 10px;
    width: auto;
  }
}

</style>
